home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 4: GNU Archives / Linux Cubed Series 4 - GNU Archives.iso / gnu / binutils.7 / binutils / binutils-2.7 / gas / config / tc-w65.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-07-04  |  23.3 KB  |  1,246 lines

  1. /* tc-w65.c -- Assemble code for the W65816
  2.  
  3.    Copyright (C) 1995 Free Software Foundation.
  4.  
  5.    This file is part of GAS, the GNU Assembler.
  6.  
  7.    GAS is free software; you can redistribute it and/or modify
  8.    it under the terms of the GNU General Public License as published by
  9.    the Free Software Foundation; either version 2, or (at your option)
  10.    any later version.
  11.  
  12.    GAS is distributed in the hope that it will be useful,
  13.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.    GNU General Public License for more details.
  16.  
  17.    You should have received a copy of the GNU General Public License
  18.    along with GAS; see the file COPYING.  If not, write to
  19.    the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
  20.  
  21. /*
  22.    Written By Steve Chamberlain
  23.    sac@cygnus.com
  24.  */
  25.  
  26. #include <stdio.h>
  27. #include "as.h"
  28. #include "bfd.h"
  29. #include "subsegs.h"
  30. #define DEFINE_TABLE
  31. #include "../opcodes/w65-opc.h"
  32. #include <ctype.h>
  33.  
  34. const char comment_chars[] = "!";
  35. CONST char line_separator_chars[] = ";";
  36. const char line_comment_chars[] = "!#";
  37.  
  38. /* This table describes all the machine specific pseudo-ops the assembler
  39.    has to support.  The fields are:
  40.    pseudo-op name without dot
  41.    function to call to execute this pseudo-op
  42.    Integer arg to pass to the function
  43.  */
  44.  
  45. #define OP_BCC    0x90
  46. #define OP_BCS    0xB0
  47. #define OP_BEQ    0xF0
  48. #define OP_BMI    0x30
  49. #define OP_BNE    0xD0
  50. #define OP_BPL    0x10
  51. #define OP_BRA    0x80
  52. #define OP_BRL    0x82
  53. #define OP_BVC    0x50
  54. #define OP_BVS    0x70
  55.  
  56. void s_longa ();
  57. const pseudo_typeS md_pseudo_table[] =
  58. {
  59.   {"int", cons, 2},
  60.   {"word", cons, 2},
  61.   {"longa", s_longa, 0},
  62.   {"longi", s_longa, 1},
  63.   {0, 0, 0}
  64. };
  65.  
  66.  
  67. void cons ();
  68. void s_align_bytes ();
  69.  
  70.  
  71. /*int md_reloc_size; */
  72.  
  73. static int relax;        /* set if -relax seen */
  74.  
  75. const char EXP_CHARS[] = "eE";
  76.  
  77. /* Chars that mean this number is a floating point constant */
  78. /* As in 0f12.456 */
  79. /* or    0d1.2345e12 */
  80. const char FLT_CHARS[] = "rRsSfFdDxXpP";
  81.  
  82.  
  83.  
  84. static struct hash_control *opcode_hash_control;    /* Opcode mnemonics */
  85.  
  86. int M;                /* M flag */
  87. int X;                /* X flag */
  88.  
  89.  
  90.  
  91.  
  92. #define C(a,b) ENCODE_RELAX(a,b)
  93. #define ENCODE_RELAX(what,length) (((what) << 2) + (length))
  94.  
  95. #define GET_WHAT(x) ((x>>2))
  96.  
  97. #define BYTE_DISP 1
  98. #define WORD_DISP 2
  99. #define UNDEF_BYTE_DISP 0
  100. #define UNDEF_WORD_DISP 3
  101.  
  102. #define COND_BRANCH     1
  103. #define UNCOND_BRANCH   2
  104. #define END     3
  105.  
  106. #define BYTE_F 127        /* How far we can branch forwards */
  107. #define BYTE_B -126        /* How far we can branch backwards */
  108. #define WORD_F 32767
  109. #define WORD_B 32768
  110.  
  111. relax_typeS md_relax_table[C (END, 0)];
  112.  
  113. /*
  114.    This function is called once, at assembler startup time.  This should
  115.    set up all the tables, etc that the MD part of the assembler needs
  116.  */
  117.  
  118.  
  119. void
  120. s_longa (xmode)
  121. {
  122.   int *p = xmode ? &X : &M;
  123.   while (*input_line_pointer == ' ')
  124.     input_line_pointer++;
  125.   if (strncmp (input_line_pointer, "on", 2) == 0)
  126.     {
  127.       input_line_pointer += 2;
  128.       *p = 0;
  129.     }
  130.   else if (strncmp (input_line_pointer, "off", 3) == 0)
  131.     {
  132.       *p = 1;
  133.       input_line_pointer += 3;
  134.     }
  135.   else
  136.     as_bad ("need on or off.");
  137.   demand_empty_rest_of_line ();
  138. }
  139. void
  140. md_begin ()
  141. {
  142.   relax_typeS *table;
  143.   struct opinfo *opcode;
  144.   char *prev_name = "";
  145.  
  146.   opcode_hash_control = hash_new ();
  147.  
  148.   /* Insert unique names into hash table */
  149.   for (opcode = optable; opcode->name; opcode++)
  150.     {
  151.       if (strcmp (prev_name, opcode->name))
  152.     {
  153.       prev_name = opcode->name;
  154.       hash_insert (opcode_hash_control, opcode->name, (char *) opcode);
  155.     }
  156.       else
  157.     {
  158.       /* Make all the opcodes with the same name point to the same
  159.          string */
  160.       opcode->name = prev_name;
  161.     }
  162.     }
  163.  
  164.  
  165.   /* Initialize the relax table.  We use a local variable to avoid
  166.      warnings about modifying a supposedly const data structure.  */
  167.   table = (relax_typeS *) md_relax_table;
  168.   table[C (COND_BRANCH, BYTE_DISP)].rlx_forward = BYTE_F;
  169.   table[C (COND_BRANCH, BYTE_DISP)].rlx_backward = BYTE_B;
  170.   table[C (COND_BRANCH, BYTE_DISP)].rlx_length = 2;
  171.   table[C (COND_BRANCH, BYTE_DISP)].rlx_more = C (COND_BRANCH, WORD_DISP);
  172.  
  173.   table[C (COND_BRANCH, WORD_DISP)].rlx_forward = WORD_F;
  174.   table[C (COND_BRANCH, WORD_DISP)].rlx_backward = WORD_B;
  175.   table[C (COND_BRANCH, WORD_DISP)].rlx_length = 5;
  176.   table[C (COND_BRANCH, WORD_DISP)].rlx_more = 0;
  177.  
  178.   table[C (UNCOND_BRANCH, BYTE_DISP)].rlx_forward = BYTE_F;
  179.   table[C (UNCOND_BRANCH, BYTE_DISP)].rlx_backward = BYTE_B;
  180.   table[C (UNCOND_BRANCH, BYTE_DISP)].rlx_length = 2;
  181.   table[C (UNCOND_BRANCH, BYTE_DISP)].rlx_more = C (UNCOND_BRANCH, WORD_DISP);
  182.  
  183.   table[C (UNCOND_BRANCH, WORD_DISP)].rlx_forward = WORD_F;
  184.   table[C (UNCOND_BRANCH, WORD_DISP)].rlx_backward = WORD_B;
  185.   table[C (UNCOND_BRANCH, WORD_DISP)].rlx_length = 3;
  186.   table[C (UNCOND_BRANCH, WORD_DISP)].rlx_more = 0;
  187.  
  188.   flag_signed_overflow_ok = 1;
  189. }
  190.  
  191. static expressionS immediate;    /* absolute expression */
  192. static expressionS immediate1;    /* absolute expression */
  193.  
  194.  
  195. static symbolS *
  196. dot ()
  197. {
  198.   const char *fake;
  199.  
  200.   /* JF: '.' is pseudo symbol with value of current location
  201.      in current segment.  */
  202.   fake = FAKE_LABEL_NAME;
  203.   return symbol_new (fake,
  204.              now_seg,
  205.              (valueT) frag_now_fix (),
  206.              frag_now);
  207.  
  208. }
  209.  
  210. int expr_size;
  211. int expr_shift;
  212. int tc_cons_reloc;
  213. void
  214. w65_expression (dest, bytes)
  215.      expressionS *dest;
  216.      unsigned int bytes;
  217. {
  218.   expr_size = 0;
  219.   expr_shift = 0;
  220.   tc_cons_reloc = 0;
  221.   while (*input_line_pointer == ' ')
  222.     input_line_pointer++;
  223.  
  224.   if (*input_line_pointer == '<')
  225.     {
  226.       expr_size = 1;
  227.       input_line_pointer++;
  228.     }
  229.   else if (*input_line_pointer == '>')
  230.     {
  231.       expr_shift = 1;
  232.       input_line_pointer++;
  233.     }
  234.   else if (*input_line_pointer == '^')
  235.     {
  236.       expr_shift = 2;
  237.       input_line_pointer++;
  238.     }
  239.  
  240.   expr (0, dest);
  241. }
  242.  
  243. int amode;
  244. static
  245. char *
  246. parse_exp (s, bytes)
  247.      char *s;
  248.      int bytes;
  249. {
  250.   char *save;
  251.   char *new;
  252.  
  253.   save = input_line_pointer;
  254.   input_line_pointer = s;
  255.   w65_expression (&immediate, bytes);
  256.   if (immediate.X_op == O_absent)
  257.     as_bad ("missing operand");
  258.   new = input_line_pointer;
  259.   input_line_pointer = save;
  260.   return new;
  261. }
  262.  
  263.  
  264. static
  265. char *
  266. get_operands (info, ptr)
  267.      struct opinfo *info;
  268.      char *ptr;
  269. {
  270.   register int override_len = 0;
  271.   register int bytes = 0;
  272.   while (*ptr == ' ')
  273.     ptr++;
  274.  
  275.   if (ptr[0] == '#')
  276.     {
  277.       ptr++;
  278.       switch (info->amode)
  279.     {
  280.     case ADDR_IMMTOI:
  281.       bytes = X ? 1 : 2;
  282.       amode = ADDR_IMMTOI;
  283.       break;
  284.     case ADDR_IMMTOA:
  285.       bytes = M ? 1 : 2;
  286.       amode = ADDR_IMMTOA;
  287.       break;
  288.     case ADDR_IMMCOP:
  289.       bytes = 1;
  290.       amode = ADDR_IMMCOP;
  291.       break;
  292.     case ADDR_DIR:
  293.       bytes = 2;
  294.       amode = ADDR_ABS;
  295.       break;
  296.     default:
  297.       abort ();
  298.       break;
  299.     }
  300.       ptr = parse_exp (ptr);
  301.     }
  302.   else if (ptr[0] == '!')
  303.     {
  304.       ptr = parse_exp (ptr + 1);
  305.       if (ptr[0] == ',')
  306.     {
  307.       if (ptr[1] == 'y')
  308.         {
  309.           amode = ADDR_ABS_IDX_Y;
  310.           bytes = 2;
  311.           ptr += 2;
  312.         }
  313.       else if (ptr[1] == 'x')
  314.         {
  315.           amode = ADDR_ABS_IDX_X;
  316.           bytes = 2;
  317.           ptr += 2;
  318.         }
  319.       else
  320.         {
  321.           as_bad ("syntax error after <exp");
  322.         }
  323.     }
  324.       else
  325.     {
  326.       amode = ADDR_ABS;
  327.       bytes = 2;
  328.     }
  329.     }
  330.   else if (ptr[0] == '>')
  331.     {
  332.       ptr = parse_exp (ptr + 1);
  333.       if (ptr[0] == ',' && ptr[1] == 'x')
  334.     {
  335.       amode = ADDR_ABS_LONG_IDX_X;
  336.       bytes = 3;
  337.       ptr += 2;
  338.     }
  339.       else
  340.     {
  341.       amode = ADDR_ABS_LONG;
  342.       bytes = 3;
  343.     }
  344.     }
  345.   else if (ptr[0] == '<')
  346.     {
  347.       ptr = parse_exp (ptr + 1);
  348.       if (ptr[0] == ',')
  349.     {
  350.       if (ptr[1] == 'y')
  351.         {
  352.           amode = ADDR_DIR_IDX_Y;
  353.           ptr += 2;
  354.           bytes = 2;
  355.         }
  356.       else if (ptr[1] == 'x')
  357.         {
  358.           amode = ADDR_DIR_IDX_X;
  359.           ptr += 2;
  360.           bytes = 2;
  361.         }
  362.       else
  363.         {
  364.           as_bad ("syntax error after <exp");
  365.         }
  366.     }
  367.       else
  368.     {
  369.       amode = ADDR_DIR;
  370.       bytes = 1;
  371.     }
  372.     }
  373.   else if (ptr[0] == 'a')
  374.     {
  375.       amode = ADDR_ACC;
  376.     }
  377.   else if (ptr[0] == '(')
  378.     {
  379.       /* Look for (exp),y
  380.      (<exp),y
  381.      (exp,x)
  382.      (<exp,x)
  383.      (exp)
  384.      (!exp)
  385.      (exp)
  386.      (<exp)
  387.      (exp,x)
  388.      (!exp,x)
  389.      (exp,s)
  390.      (exp,s),y */
  391.  
  392.       ptr++;
  393.       if (ptr[0] == '<')
  394.     {
  395.       override_len = 1;
  396.       ptr++;
  397.     }
  398.       else if (ptr[0] == '!')
  399.     {
  400.       override_len = 2;
  401.       ptr++;
  402.     }
  403.       else if (ptr[0] == '>')
  404.     {
  405.       override_len = 3;
  406.       ptr++;
  407.     }
  408.       else
  409.     {
  410.       override_len = 0;
  411.     }
  412.       ptr = parse_exp (ptr);
  413.  
  414.       if (ptr[0] == ',')
  415.     {
  416.       ptr++;
  417.       if (ptr[0] == 'x' && ptr[1] == ')')
  418.         {
  419.           ptr += 2;
  420.  
  421.           if (override_len == 1)
  422.         {
  423.           amode = ADDR_DIR_IDX_IND_X;
  424.           bytes = 2;
  425.         }
  426.           else
  427.         {
  428.           amode = ADDR_ABS_IND_IDX;
  429.           bytes = 2;
  430.         }
  431.         }
  432.       else if (ptr[0] == 's' && ptr[1] == ')' && ptr[2] == ',' && ptr[3] == 'y')
  433.         {
  434.           amode = ADDR_STACK_REL_INDX_IDX;
  435.           bytes = 1;
  436.           ptr += 4;
  437.         }
  438.     }
  439.       else if (ptr[0] == ')')
  440.     {
  441.       if (ptr[1] == ',' && ptr[2] == 'y')
  442.         {
  443.           amode = ADDR_DIR_IND_IDX_Y;
  444.           ptr += 3;
  445.           bytes = 2;
  446.         }
  447.       else
  448.         {
  449.           if (override_len == 1)
  450.         {
  451.           amode = ADDR_DIR_IND;
  452.           bytes = 1;
  453.         }
  454.           else
  455.         {
  456.           amode = ADDR_ABS_IND;
  457.           bytes = 2;
  458.         }
  459.           ptr++;
  460.  
  461.         }
  462.     }
  463.  
  464.     }
  465.   else if (ptr[0] == '[')
  466.     {
  467.       ptr = parse_exp (ptr + 1);
  468.       if (ptr[0] == ']')
  469.     {
  470.       ptr++;
  471.       if (ptr[0] == ',' && ptr[1] == 'y')
  472.         {
  473.           bytes = 1;
  474.           amode = ADDR_DIR_IND_IDX_Y_LONG;
  475.           ptr += 2;
  476.         }
  477.       else
  478.         {
  479.           if (info->code == O_jmp) 
  480.         {
  481.         bytes = 2;
  482.         amode = ADDR_ABS_IND_LONG;
  483.           } 
  484.           else 
  485. {
  486.         bytes = 1;
  487.           
  488.         amode = ADDR_DIR_IND_LONG;
  489.           }
  490.         }
  491.     }
  492.     }
  493.   else
  494.     {
  495.       ptr = parse_exp (ptr, 2);
  496.       if (ptr[0] == ',')
  497.     {
  498.       if (ptr[1] == 'y')
  499.         {
  500.           if (override_len == 1)
  501.         {
  502.           bytes = 1;
  503.           amode = ADDR_DIR_IDX_Y;
  504.         }
  505.           else
  506.         {
  507.           amode = ADDR_ABS_IDX_Y;
  508.           bytes = 2;
  509.         }
  510.           ptr += 2;
  511.         }
  512.       else if (ptr[1] == 'x')
  513.         {
  514.           if (override_len == 1)
  515.         {
  516.           amode = ADDR_DIR_IDX_X;
  517.           bytes = 1;
  518.         }
  519.           else
  520.         {
  521.           amode = ADDR_ABS_IDX_X;
  522.           bytes = 2;
  523.         }
  524.           ptr += 2;
  525.         }
  526.       else if (ptr[1] == 's')
  527.         {
  528.           bytes = 1;
  529.           amode = ADDR_STACK_REL;
  530.           ptr += 2;
  531.         }
  532.       else
  533.         {
  534.           bytes = 1;
  535.           immediate1 = immediate;
  536.           ptr = parse_exp (ptr + 1);
  537.           amode = ADDR_BLOCK_MOVE;
  538.         }
  539.     }
  540.       else
  541.     {
  542.       switch (info->amode)
  543.         {
  544.         case ADDR_PC_REL:
  545.           amode = ADDR_PC_REL;
  546.           bytes = 1;
  547.           break;
  548.         case ADDR_PC_REL_LONG:
  549.           amode = ADDR_PC_REL_LONG;
  550.           bytes = 2;
  551.           break;
  552.         default:
  553.           if (override_len == 1)
  554.         {
  555.           amode = ADDR_DIR;
  556.           bytes = 1;
  557.         }
  558.           else if (override_len == 3)
  559.         {
  560.           bytes = 3;
  561.           amode = ADDR_ABS_LONG;
  562.         }
  563.           else
  564.         {
  565.           amode = ADDR_ABS;
  566.           bytes = 2;
  567.         }
  568.         }
  569.     }
  570.     }
  571.  
  572.   switch (bytes)
  573.     {
  574.     case 1:
  575.       switch (expr_shift)
  576.     {
  577.     case 0:
  578.       if (amode == ADDR_DIR)
  579.     tc_cons_reloc = R_W65_DP;
  580.       else
  581. tc_cons_reloc = R_W65_ABS8;
  582.       break;
  583.     case 1:
  584.       tc_cons_reloc = R_W65_ABS8S8;
  585.       break;
  586.     case 2:
  587.       tc_cons_reloc = R_W65_ABS8S16;
  588.       break;
  589.     }
  590.       break;
  591.     case 2:
  592.       switch (expr_shift)
  593.     {
  594.     case 0:
  595.       tc_cons_reloc = R_W65_ABS16;
  596.       break;
  597.     case 1:
  598.       tc_cons_reloc = R_W65_ABS16S8;
  599.       break;
  600.     case 2:
  601.       tc_cons_reloc = R_W65_ABS16S16;
  602.       break;
  603.     }
  604.     }
  605.   return ptr;
  606. }
  607.  
  608. /* Passed a pointer to a list of opcodes which use different
  609.    addressing modes, return the opcode which matches the opcodes
  610.    provided
  611.  */
  612.  
  613. static
  614. struct opinfo *
  615. get_specific (opcode)
  616.      struct opinfo *opcode;
  617. {
  618.   int ocode = opcode->code;
  619.  
  620.   for (; opcode->code == ocode; opcode++)
  621.     {
  622.       if (opcode->amode == amode)
  623.     return opcode;
  624.     }
  625.   return 0;
  626. }
  627.  
  628. int
  629. check (operand, low, high)
  630.      expressionS *operand;
  631.      int low;
  632.      int high;
  633. {
  634.   if (operand->X_op != O_constant
  635.       || operand->X_add_number < low
  636.       || operand->X_add_number > high)
  637.     {
  638.       as_bad ("operand must be absolute in range %d..%d", low, high);
  639.     }
  640.   return operand->X_add_number;
  641. }
  642.  
  643.  
  644. static int log2[] =
  645. {0, 0, 1, 0, 2};
  646.  
  647. /* Now we know what sort of opcodes it is, lets build the bytes -
  648.  */
  649. static void
  650. build_Mytes (opcode)
  651.      struct opinfo *opcode;
  652. {
  653.   int size;
  654.   int type;
  655.   int pcrel;
  656.   char *output;
  657.  
  658.   if (opcode->amode == ADDR_IMPLIED)
  659.     {
  660.       output = frag_more (1);
  661.     }
  662.   else if (opcode->amode == ADDR_PC_REL)
  663.     {
  664.       int type;
  665.       /* This is a relaxable insn, so we do some special handling */
  666.       type = opcode->val == OP_BRA ? UNCOND_BRANCH : COND_BRANCH;
  667.       output = frag_var (rs_machine_dependent,
  668.              md_relax_table[C (type, WORD_DISP)].rlx_length,
  669.              md_relax_table[C (type, BYTE_DISP)].rlx_length,
  670.              C (type, UNDEF_BYTE_DISP),
  671.              immediate.X_add_symbol,
  672.              immediate.X_add_number,
  673.              0);
  674.     }
  675.   else
  676.     {
  677.       switch (opcode->amode)
  678.     {
  679.       GETINFO (size, type, pcrel);
  680.     }
  681.  
  682.       /* If something special was done in the
  683.      expression modify the reloc type */
  684.       if (tc_cons_reloc)
  685.     {
  686.       type = tc_cons_reloc;
  687.     }
  688.  
  689.  
  690.  
  691.       /* 1 byte for the opcode + the bytes for the addrmode */
  692.       output = frag_more (size + 1);
  693.  
  694.       if (opcode->amode == ADDR_BLOCK_MOVE)
  695.     {
  696.       /* Two relocs for this one */
  697.       fix_new_exp (frag_now,
  698.                output + 1 - frag_now->fr_literal,
  699.                1,
  700.                &immediate,
  701.                0,
  702.                R_W65_ABS8S16);
  703.  
  704.       fix_new_exp (frag_now,
  705.                output + 2 - frag_now->fr_literal,
  706.                1,
  707.                &immediate1,
  708.                0,
  709.                R_W65_ABS8S16);
  710.     }
  711.       else if (type >= 0
  712.            && opcode->amode != ADDR_IMPLIED
  713.            && opcode->amode != ADDR_ACC
  714.            && opcode->amode != ADDR_STACK)
  715.     {
  716.       fix_new_exp (frag_now,
  717.                output + 1 - frag_now->fr_literal,
  718.                size,
  719.                &immediate,
  720.                pcrel,
  721.                type);
  722.     }
  723.     }
  724.   output[0] = opcode->val;
  725. }
  726.  
  727. /* This is the guts of the machine-dependent assembler.  STR points to a
  728.    machine dependent instruction.  This function is supposed to emit
  729.    the frags/bytes it assembles to.
  730.  */
  731.  
  732. void
  733. md_assemble (str)
  734.      char *str;
  735. {
  736.   unsigned char *op_start;
  737.   unsigned char *op_end;
  738.   struct opinfo *opcode;
  739.   char name[20];
  740.   int nlen = 0;
  741.   char *p;
  742.  
  743.   /* Drop leading whitespace */
  744.   while (*str == ' ')
  745.     str++;
  746.  
  747.   /* all opcodes are three letters */
  748.   name[0] = str[0];
  749.   name[1] = str[1];
  750.   name[2] = str[2];
  751.   name[3] = 0;
  752.  
  753.   tc_cons_reloc = 0;
  754.   str += 3;
  755.   opcode = (struct opinfo *) hash_find (opcode_hash_control, name);
  756.  
  757.   if (opcode == NULL)
  758.     {
  759.       as_bad ("unknown opcode");
  760.       return;
  761.     }
  762.  
  763.   if (opcode->amode != ADDR_IMPLIED
  764.       && opcode->amode != ADDR_STACK)
  765.     {
  766.       get_operands (opcode, str);
  767.       opcode = get_specific (opcode);
  768.     }
  769.  
  770.   if (opcode == 0)
  771.     {
  772.       /* Couldn't find an opcode which matched the operands */
  773.  
  774.  
  775.       char *where = frag_more (1);
  776.  
  777.       where[0] = 0x0;
  778.       where[1] = 0x0;
  779.       as_bad ("invalid operands for opcode");
  780.       return;
  781.     }
  782.  
  783.   build_Mytes (opcode);
  784. }
  785.  
  786.  
  787. void
  788. DEFUN (tc_crawl_symbol_chain, (headers),
  789.        object_headers * headers)
  790. {
  791.   printf ("call to tc_crawl_symbol_chain \n");
  792. }
  793.  
  794. symbolS *
  795. DEFUN (md_undefined_symbol, (name),
  796.        char *name)
  797. {
  798.   return 0;
  799. }
  800.  
  801. void
  802. DEFUN (tc_headers_hook, (headers),
  803.        object_headers * headers)
  804. {
  805.   printf ("call to tc_headers_hook \n");
  806. }
  807.  
  808. /* Various routines to kill one day */
  809. /* Equal to MAX_PRECISION in atof-ieee.c */
  810. #define MAX_LITTLENUMS 6
  811.  
  812. /* Turn a string in input_line_pointer into a floating point constant of type
  813.    type, and store the appropriate bytes in *litP.  The number of LITTLENUMS
  814.    emitted is stored in *sizeP .  An error message is returned, or NULL on OK.
  815.  */
  816. char *
  817. md_atof (type, litP, sizeP)
  818.      char type;
  819.      char *litP;
  820.      int *sizeP;
  821. {
  822.   int prec;
  823.   LITTLENUM_TYPE words[MAX_LITTLENUMS];
  824.   LITTLENUM_TYPE *wordP;
  825.   char *t;
  826.   char *atof_ieee ();
  827.  
  828.   switch (type)
  829.     {
  830.     case 'f':
  831.     case 'F':
  832.     case 's':
  833.     case 'S':
  834.       prec = 2;
  835.       break;
  836.  
  837.     case 'd':
  838.     case 'D':
  839.     case 'r':
  840.     case 'R':
  841.       prec = 4;
  842.       break;
  843.  
  844.     case 'x':
  845.     case 'X':
  846.       prec = 6;
  847.       break;
  848.  
  849.     case 'p':
  850.     case 'P':
  851.       prec = 6;
  852.       break;
  853.  
  854.     default:
  855.       *sizeP = 0;
  856.       return "Bad call to MD_NTOF()";
  857.     }
  858.   t = atof_ieee (input_line_pointer, type, words);
  859.   if (t)
  860.     input_line_pointer = t;
  861.  
  862.   *sizeP = prec * sizeof (LITTLENUM_TYPE);
  863.   for (wordP = words + prec - 1; prec--;)
  864.     {
  865.       md_number_to_chars (litP, (valueT) (*wordP--), sizeof (LITTLENUM_TYPE));
  866.       litP += sizeof (LITTLENUM_TYPE);
  867.     }
  868.   return 0;
  869. }
  870.  
  871. int
  872. md_parse_option (c,a)
  873.     int c;
  874.     char *a;
  875.  
  876. {
  877.   return 1;
  878. }
  879.  
  880. int md_short_jump_size;
  881.  
  882. void
  883. tc_Nout_fix_to_chars ()
  884. {
  885.   printf ("call to tc_Nout_fix_to_chars \n");
  886.   abort ();
  887. }
  888.  
  889. void
  890. md_create_short_jump (ptr, from_Nddr, to_Nddr, frag, to_symbol)
  891.      char *ptr;
  892.      addressT from_Nddr;
  893.      addressT to_Nddr;
  894.      fragS *frag;
  895.      symbolS *to_symbol;
  896. {
  897.   as_fatal ("failed sanity check.");
  898. }
  899.  
  900. void
  901. md_create_long_jump (ptr, from_Nddr, to_Nddr, frag, to_symbol)
  902.      char *ptr;
  903.      addressT from_Nddr, to_Nddr;
  904.      fragS *frag;
  905.      symbolS *to_symbol;
  906. {
  907.   as_fatal ("failed sanity check.");
  908. }
  909.  
  910.  
  911. /*
  912. called after relaxing, change the frags so they know how big they are
  913. */
  914. void
  915. md_convert_frag (headers, seg, fragP)
  916.      object_headers *headers;
  917.      segT seg;
  918.      fragS *fragP;
  919. {
  920.   int disp_size = 0;
  921.   int inst_size = 0;
  922.   unsigned char *buffer = (unsigned char *) (fragP->fr_fix + fragP->fr_literal);
  923.  
  924.   switch (fragP->fr_subtype)
  925.     {
  926.     case C (COND_BRANCH, BYTE_DISP):
  927.     case C (UNCOND_BRANCH, BYTE_DISP):
  928.       disp_size = 1;
  929.       inst_size = 1;
  930.       break;
  931.  
  932.       /* cond branches to a known 16 bit displacement */
  933.     case C (COND_BRANCH, WORD_DISP):
  934.       switch (buffer[0])
  935.     {
  936.     case OP_BCC:
  937.     case OP_BCS:
  938.     case OP_BEQ:
  939.     case OP_BMI:
  940.     case OP_BNE:
  941.     case OP_BPL:
  942.     case OP_BVS:
  943.     case OP_BVC:
  944.       /* Invert the sense of the test */
  945.       buffer[0] ^= 0x20;
  946.       buffer[1] = 3;    /* Jump over following brl */
  947.       buffer[2] = OP_BRL;
  948.       buffer[3] = 0;
  949.       buffer[4] = 0;
  950.       disp_size = 2;
  951.       inst_size = 3;
  952.       break;
  953.     default:
  954.       abort ();
  955.     }
  956.       break;
  957.     case C (UNCOND_BRANCH, WORD_DISP):
  958.       /* Unconditional branches to a known 16 bit displacement */
  959.  
  960.       switch (buffer[0])
  961.     {
  962.     case OP_BRA:
  963.       buffer[0] = OP_BRL;
  964.       disp_size = 2;
  965.       inst_size = 1;
  966.       break;
  967.     default:
  968.       abort ();
  969.     }
  970.       break;
  971.       /* got to create a branch over a reloc here */
  972.     case C (COND_BRANCH, UNDEF_WORD_DISP):
  973.       buffer[0] ^= 0x20;    /* invert test */
  974.       buffer[1] = 3;
  975.       buffer[2] = OP_BRL;
  976.       buffer[3] = 0;
  977.       buffer[4] = 0;
  978.       fix_new (fragP,
  979.            fragP->fr_fix + 3,
  980.            4,
  981.            fragP->fr_symbol,
  982.            fragP->fr_offset,
  983.            0,
  984.            R_W65_PCR16);
  985.  
  986.       fragP->fr_fix += disp_size + inst_size;
  987.       fragP->fr_var = 0;
  988.       break;
  989.     case C (UNCOND_BRANCH, UNDEF_WORD_DISP):
  990.       buffer[0] = OP_BRL;
  991.       buffer[1] = 0;
  992.       buffer[2] = 0;
  993.       fix_new (fragP,
  994.            fragP->fr_fix + 1,
  995.            4,
  996.            fragP->fr_symbol,
  997.            fragP->fr_offset,
  998.            0,
  999.            R_W65_PCR16);
  1000.  
  1001.       fragP->fr_fix += disp_size + inst_size;
  1002.       fragP->fr_var = 0;
  1003.       break;
  1004.     default:
  1005.       abort ();
  1006.     }
  1007.   if (inst_size)
  1008.     {
  1009.       /* Get the address of the end of the instruction */
  1010.       int next_inst = fragP->fr_fix + fragP->fr_address + disp_size + inst_size;
  1011.       int targ_addr = (S_GET_VALUE (fragP->fr_symbol) +
  1012.                fragP->fr_offset);
  1013.       int disp = targ_addr - next_inst;
  1014.  
  1015.       md_number_to_chars (buffer + inst_size, disp, disp_size);
  1016.       fragP->fr_fix += disp_size + inst_size;
  1017.       fragP->fr_var = 0;
  1018.     }
  1019. }
  1020.  
  1021.  
  1022. valueT
  1023. DEFUN (md_section_align, (seg, size),
  1024.        segT seg AND
  1025.        valueT size)
  1026. {
  1027.   return ((size + (1 << section_alignment[(int) seg]) - 1)
  1028.       & (-1 << section_alignment[(int) seg]));
  1029.  
  1030. }
  1031.  
  1032. void
  1033. md_apply_fix (fixP, val)
  1034.      fixS *fixP;
  1035.      long val;
  1036. {
  1037.   char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
  1038.   int addr = fixP->fx_frag->fr_address + fixP->fx_where;
  1039.  
  1040.   if (fixP->fx_r_type == 0)
  1041.     {
  1042.       if (fixP->fx_size == 1)
  1043.     fixP->fx_r_type = R_W65_ABS8;
  1044.       else
  1045.     fixP->fx_r_type = R_W65_ABS16;
  1046.     }
  1047.  
  1048.   switch (fixP->fx_r_type)
  1049.     {
  1050.     case R_W65_ABS8S16:
  1051.       val >>= 8;
  1052.     case R_W65_ABS8S8:
  1053.       val >>= 8;
  1054.     case R_W65_ABS8:
  1055.       *buf++ = val;
  1056.       break;
  1057.     case R_W65_ABS16S16:
  1058.       val >>= 8;
  1059.     case R_W65_ABS16S8:
  1060.       val >>= 8;
  1061.     case R_W65_ABS16:
  1062.       *buf++ = val >> 0;
  1063.       *buf++ = val >> 8;
  1064.       break;
  1065.     case R_W65_ABS24:
  1066.       *buf++ = val >> 0;
  1067.       *buf++ = val >> 8;
  1068.       *buf++ = val >> 16;
  1069.       break;
  1070.     case R_W65_PCR8:
  1071.       *buf++ = val - addr - 1;
  1072.       break;
  1073.     case R_W65_PCR16:
  1074.       val = val - addr - 1;
  1075.       *buf++ = val;
  1076.       *buf++ = val >> 8;
  1077.       break;
  1078.     case R_W65_DP:
  1079.       *buf++ = val;
  1080.       break;
  1081.  
  1082.     default:
  1083.       abort ();
  1084.     }
  1085. }
  1086.  
  1087. int md_long_jump_size;
  1088.  
  1089. /* Put number into target byte order */
  1090.  
  1091. void
  1092. md_number_to_chars (ptr, use, nbytes)
  1093.      char *ptr;
  1094.      valueT use;
  1095.      int nbytes;
  1096. {
  1097.   number_to_chars_littleendian (ptr, use, nbytes);
  1098. }
  1099.  
  1100. long
  1101. md_pcrel_from (fixP)
  1102.      fixS *fixP;
  1103. {
  1104.   int gap = fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address - 1;
  1105.   return gap;
  1106. }
  1107.  
  1108. void
  1109. tc_coff_symbol_emit_hook (x)
  1110.     struct symbol *x;
  1111. {
  1112. }
  1113.  
  1114. short
  1115. tc_coff_fix2rtype (fix_ptr)
  1116.      fixS *fix_ptr;
  1117. {
  1118.   return fix_ptr->fx_r_type;
  1119. }
  1120.  
  1121. void
  1122. tc_reloc_mangle (fix_ptr, intr, base)
  1123.      fixS *fix_ptr;
  1124.      struct internal_reloc *intr;
  1125.      bfd_vma base;
  1126.  
  1127. {
  1128.   symbolS *symbol_ptr;
  1129.  
  1130.   symbol_ptr = fix_ptr->fx_addsy;
  1131.  
  1132.   /* If this relocation is attached to a symbol then it's ok
  1133.      to output it */
  1134.   if (fix_ptr->fx_r_type == RELOC_32)
  1135.     {
  1136.       /* cons likes to create reloc32's whatever the size of the reloc..
  1137.        */
  1138.       switch (fix_ptr->fx_size)
  1139.     {
  1140.     case 2:
  1141.       intr->r_type = R_IMM16;
  1142.       break;
  1143.     case 1:
  1144.       intr->r_type = R_IMM8;
  1145.       break;
  1146.     default:
  1147.       abort ();
  1148.     }
  1149.     }
  1150.   else
  1151.     {
  1152.       if (fix_ptr->fx_size == 4)
  1153.     intr->r_type = R_W65_ABS24;
  1154.       else
  1155.     intr->r_type = fix_ptr->fx_r_type;
  1156.     }
  1157.  
  1158.   intr->r_vaddr = fix_ptr->fx_frag->fr_address + fix_ptr->fx_where + base;
  1159.   intr->r_offset = fix_ptr->fx_offset;
  1160.  
  1161.   /* Turn the segment of the symbol into an offset.  */
  1162.   if (symbol_ptr)
  1163.     {
  1164.       symbolS *dot;
  1165.  
  1166.       dot = segment_info[S_GET_SEGMENT (symbol_ptr)].dot;
  1167.       if (dot)
  1168.     {
  1169.       intr->r_offset += S_GET_VALUE (symbol_ptr);
  1170.       intr->r_symndx = dot->sy_number;
  1171.     }
  1172.       else
  1173.     {
  1174.       intr->r_symndx = symbol_ptr->sy_number;
  1175.     }
  1176.     }
  1177.   else
  1178.     {
  1179.       intr->r_symndx = -1;
  1180.     }
  1181. }
  1182.  
  1183. int
  1184. tc_coff_sizemachdep (frag)
  1185.      fragS *frag;
  1186. {
  1187.   return md_relax_table[frag->fr_subtype].rlx_length;
  1188. }
  1189.  
  1190.  
  1191.  
  1192.  
  1193.  
  1194. /*
  1195. called just before address relaxation, return the length
  1196. by which a fragment must grow to reach it's destination
  1197. */
  1198. int
  1199. md_estimate_size_before_relax (fragP, segment_type)
  1200.      register fragS *fragP;
  1201.      register segT segment_type;
  1202. {
  1203.   int what = GET_WHAT (fragP->fr_subtype);
  1204.  
  1205.   switch (fragP->fr_subtype)
  1206.     {
  1207.     default:
  1208.       abort ();
  1209.     case C (COND_BRANCH, UNDEF_BYTE_DISP):
  1210.     case C (UNCOND_BRANCH, UNDEF_BYTE_DISP):
  1211.       /* used to be a branch to somewhere which was unknown */
  1212.       if (S_GET_SEGMENT (fragP->fr_symbol) == segment_type)
  1213.     {
  1214.       /* Got a symbol and it's defined in this segment, become byte
  1215.      sized - maybe it will fix up */
  1216.       fragP->fr_subtype = C (what, BYTE_DISP);
  1217.       fragP->fr_var = md_relax_table[C (what, BYTE_DISP)].rlx_length;
  1218.     }
  1219.       else
  1220.     {
  1221.       /* Its got a segment, but its not ours, so it will always be long */
  1222.       fragP->fr_subtype = C (what, UNDEF_WORD_DISP);
  1223.       fragP->fr_var = md_relax_table[C (what, WORD_DISP)].rlx_length;
  1224.       return md_relax_table[C (what, WORD_DISP)].rlx_length;
  1225.     }
  1226.     }
  1227.   return fragP->fr_var;
  1228. }
  1229.  
  1230.  
  1231.  
  1232. CONST char *md_shortopts = "";
  1233. struct option md_longopts[] = {
  1234. #define OPTION_RELAX (OPTION_MD_BASE)
  1235.   {NULL, no_argument, NULL, 0}
  1236. };
  1237.  
  1238. void
  1239. md_show_usage (stream)
  1240.      FILE *stream;
  1241. {
  1242.  
  1243. }
  1244.  
  1245. size_t md_longopts_size = sizeof(md_longopts);
  1246.